#include "Client.h"
#include "Slot.h"
#include "Card.h"

Client::Client(Table* _table){
  
  emptyActiveCard = new Card(hearts, active, 999);
  emptyDeckCard = new Card(hearts, deck, 999);
  emptyPillageCard = new Card(hearts, pillage, 999);
  emptySpoilsCard = new Card(hearts, spoils, 999);
  emptyHandCard = new Card(hearts, hand, 999);
  emptySlot.setX(0);
  emptySlot.setY(0);
  emptySlot.setCard(emptyActiveCard);
  table = _table;
  cardX=0;
  cardY=0;
  suit=0;
  number=0;
  dragX=0;
  dragY=0;
  //window being the box that we're playing in
  windowMaxX = 78;
  windowMaxY = 36;
  windowXOffset = 0;
  windowYOffset = 1;
  initializeDisplay();
  
}

void Client::initializeDisplay(){
  gameDisplay.setTable(table);
  gameDisplay.drawBox(windowXOffset,windowYOffset, windowMaxX,windowMaxY,0);

//Iterates through and sets all possible locations into the Slot objects
  for(int i = 0; i < 8; i++){
    p1CardSlots[i].setX(18 + 6*i);
    p1CardSlots[i].setY(27);
    p1CardSlots[i].setCard(emptyHandCard);
  }
  for(int i=0; i<2; i++){
    p2CardSlots[i].setX(8);
    p2CardSlots[i].setY(12 + 5*i);
    p2CardSlots[i].setCard(emptyDeckCard);
  }
  for(int i=0; i<2; i++){
    p3CardSlots[i].setX(32 + 6*i);
    p3CardSlots[i].setY(4);
    p3CardSlots[i].setCard(emptyDeckCard);
  }
  for(int i=0; i<2; i++){
    p4CardSlots[i].setX(64);
    p4CardSlots[i].setY(12 + 5 *i);
    p4CardSlots[i].setCard(emptyDeckCard);
  }


//Change the coordinates of the cards here if necessary
  activeSlots[0].setX(36);
  activeSlots[0].setY(21);
  activeSlots[1].setX(17);
  activeSlots[1].setY(15);
  activeSlots[2].setX(36);
  activeSlots[2].setY(9);
  activeSlots[3].setX(55);
  activeSlots[3].setY(15);
  pillageSlot.setX(32);
  pillageSlot.setY(15);
  pillageSlot.setCard(emptyPillageCard);
  spoilsSlot.setX(40);
  spoilsSlot.setY(15);
  spoilsSlot.setCard(emptySpoilsCard);
}

void Client::drawTable(Table* table){ 
  Rank tempRank;
  Suit tempSuit;
  int tempID;
  Card tempCard = Card(hearts, joker, 9999);//dummy card
//the called from within a loooooop
  //Creates the box to cover previous table
  gameDisplay.drawBox(windowXOffset,windowYOffset, windowMaxX,windowMaxY,0); 
  //Next line shows the Deck of rank 18
  gameDisplay.displayCard(p1CardSlots[0].getX(),p1CardSlots[0].getY(), 1, 18,0);
  //This loop gives the player1's hand
  int handSize = table->players.at(0).getHand()->size();
  for(int i = 0; i < handSize; i++){
    tempRank = table->players.at(0).getHand()->at(i)->getRank();
    tempSuit = table->players.at(0).getHand()->at(i)->getSuit();
    tempID = table->players.at(0).getHand()->at(i)->getID();
    tempCard = Card(tempSuit, tempRank, tempID);//constructs a new card based on the player's real card
    gameDisplay.displayCard(p1CardSlots[i+1].getX(),p1CardSlots[i+1].getY(), tempSuit,tempRank,0);
    //it is then vital to also assign the card to the associated Slot
    p1CardSlots[i+1].setCard(&tempCard);//assigns the sslot's card to thisCard
  } 

//need to be set in slots properly
  //player2's Deck and Hand
  gameDisplay.displayCard(p2CardSlots[0].getX(),p2CardSlots[0].getY(), 2,18,0);
  gameDisplay.displayCard(p2CardSlots[1].getX(),p2CardSlots[1].getY(), 2,14,0);
  //player3's Deck and Hand
  gameDisplay.displayCard(p3CardSlots[0].getX(),p3CardSlots[0].getY(), 3,18,0);
  gameDisplay.displayCard(p3CardSlots[1].getX(),p3CardSlots[1].getY(), 3,14,0);
  //player4's Deck and Hand
  gameDisplay.displayCard(p4CardSlots[0].getX(),p4CardSlots[0].getY(), 4,18,0);
  gameDisplay.displayCard(p4CardSlots[1].getX(),p4CardSlots[1].getY(), 4,14,0);

  

  for(int i=0; i<(table->players.size()); i++){ // Adds empty cards to each slot. 
    activeSlots[i].setCard(emptyActiveCard);
  }
  for(int i=0; i< table->activeCards.size();i++){ //iterate through each card in active cards 
    for(int j=0; j<table->players.size(); j++){ // iterate through each player checking to see if they are the correct player
      if(
      &(table->players.at(j) ) == (table->activeCards.at(i)->getOwner() )//You can't compare player objects but you can compare their addresses!!!!!! wow. i was so glad when i thought of this
      ){//if the owner of the card is a player 
        activeSlots[j].setCard(table->activeCards.at(i)); //set the actives slot of that player to the card 
        tempRank=activeSlots[i].getCard()->getRank(); 
        tempSuit=activeSlots[i].getCard()->getSuit();
        tempID=activeSlots[i].getCard()->getID();
      } 
      else{
        tempRank=active;
        tempSuit=hearts;
        tempID=0;
      }
    gameDisplay.displayCard(activeSlots[i].getX(),activeSlots[i].getY(), tempSuit,tempRank,0);

    } 
  }
  
  //Pillage and Spoils
//needs to be set in the slots properly still:
  gameDisplay.displayCard(pillageSlot.getX(),pillageSlot.getY(),1,pillage,0);
  gameDisplay.displayCard(spoilsSlot.getX(),pillageSlot.getY(),1,spoils,0);

	//USE THIS FOR DEBUGGING - for seeing what a card value is
/* 
    int tempRank = table->players.at(0).getHand()->at(2)->getRank(); //modify this and the one below
    int tempSuit = table->players.at(0).getHand()->at(2)->getSuit();
    cout<<tempRank<<endl;
    gameDisplay.displayCard(0,0, tempSuit, tempRank,0);
*/

}

Slot Client::checkHitBoxes(){

    for(int i=0; i<8; i++){
      if(between (p1CardSlots[i].getX(), clickX, p1CardSlots[i].getX()+5)){
	if(between(p1CardSlots[i].getY(), clickY, p1CardSlots[i].getY()+4)){
          return p1CardSlots[i];
        }
      }
    }
    for(int i=0; i<2; i++){
      if(between (p2CardSlots[i].getX(), clickX, p2CardSlots[i].getX()+5)){
	if(between(p2CardSlots[i].getY(), clickY, p2CardSlots[i].getY()+4)){
          return p2CardSlots[i];
        }
      }
    }
    for(int i=0; i<2; i++){
      if(between (p3CardSlots[i].getX(), clickX, p3CardSlots[i].getX()+5)){
	if(between(p3CardSlots[i].getY(), clickY, p3CardSlots[i].getY()+4)){
          return p3CardSlots[i];
        }
      }
    }
    for(int i=0; i<2; i++){
      if(between (p4CardSlots[i].getX(), clickX, p4CardSlots[i].getX()+5)){
	if(between(p4CardSlots[i].getY(), clickY, p4CardSlots[i].getY()+4)){
          return p4CardSlots[i];
        }
      }
    }

    if(between(pillageSlot.getX(), clickX, pillageSlot.getX()+5)){
      if(between(pillageSlot.getY(), clickY, pillageSlot.getX()+4)){
        return pillageSlot;
      }
    }

    if(between(spoilsSlot.getX(), clickX, spoilsSlot.getX()+5)){
      if(between(spoilsSlot.getY(), clickY, spoilsSlot.getX()+4)){
        return spoilsSlot;
      }
    }

    for(int i=0; i<3; i++){
      if(between(activeSlots[i].getX(), clickX, activeSlots[i].getX()+5)){ 
        if(between(activeSlots[i].getY(), clickY, activeSlots[i].getX()+4)){
          return activeSlots[i];
        }
      }
    }


  
  return emptySlot;
}

bool Client::between(int a, int b, int c){
  if((a < b) && (b < c)){
    return true;
  }
  return false;
}

void Client::setClickedCardToMove(Slot clickedSlot, Table* table){
//If you later wish to add players then each needs its own for loop because of the naming of the slot arrays
    //check each slot of this player one's hand.
    for(int i = 1; i < table->players.at(i).getHand()->size(); i++){// Starts at 1 because 0 is the player's deck
      //if you click card hand in hand  
      if(( clickedSlot.getX() == p1CardSlots[i].getX()) && (clickedSlot.getY() == p1CardSlots[i].getY()) ){
        
        table->players.at(0).setMoveCard(clickedSlot.getCard());//then set move that card 
      }
    }
}

void Client::updateClient(Table* table){
  drawTable(table); 
  // calls the game display to capture some input
  gameDisplay.updateScreen();
  // calls the game display to capture some input
  key = gameDisplay.captureInput();
  Slot clickedSlot = checkHitBoxes();
  
 
      // if a mouse event occurred
      if (key == -1) {
        // make a banner message
        messageString.str("");
        messageString << "A mouse event occurred x=" \
          << gameDisplay.getMouseEventX() << ", y=" \
          << gameDisplay.getMouseEventY() << ", bstate=" \
          << gameDisplay.getMouseEventButton();
        // display a banner message
        gameDisplay.bannerTop(messageString.str());
        // record the location of the mouse event
        clickX = gameDisplay.getMouseEventX();
        clickY = gameDisplay.getMouseEventY();

        // check if it was a left click
        if (gameDisplay.getMouseEventButton()&LEFT_CLICK) {
	  Slot clickedSlot = checkHitBoxes();
	  setClickedCardToMove(clickedSlot, table);//this sets a player's move based on which slot was clicked
	  Card* tempCard = clickedSlot.getCard();
	  Card thisCard = *tempCard;
	  
	  int num = thisCard.getID();
	  //cout<<num<<endl;
	  string result;
	  ostringstream convert;
	  convert <<num;
	  result = convert.str();
          gameDisplay.bannerBottom(result);
	  
	}
        // check if it was a right click
        else if (gameDisplay.getMouseEventButton()&RIGHT_CLICK) {
        }
     
    }
  
  
}


